package com.xhdx.threadpool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ExecutorDemo {

    public static void main(String[] args) {
        createThreadPoolExecutor();
        createFixedThreadPool();
        createScheduledThreadPool();
        createCachedThreadPool();
        createSingleThreadExecutor();
    }

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;
    private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    public static void createThreadPoolExecutor() {
        // 1.创建自定义线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
                KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        // 2.创建任务
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("自定义线程池-任务执行");
            }
        };
        // 3.通过线程池执行任务
        threadPoolExecutor.execute(task);
        // 4.关闭线程池
        threadPoolExecutor.shutdown();
    }

    public static void createFixedThreadPool() {
        // 1.创建定长线程池
        // public static ExecutorService newFixedThreadPool(int var0) {
        // return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS,
        // new LinkedBlockingQueue());
        // }
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        // 2.创建任务
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("定长线程池-任务执行");
            }
        };
        // 3.通过线程池执行任务
        fixedThreadPool.execute(task);
        // 4.关闭线程池
        fixedThreadPool.shutdown();
    }

    public static void createScheduledThreadPool() {
        // 1.创建定时线程池
        // public ScheduledThreadPoolExecutor(int var1) {
        // super(var1, 2147483647, 0L, TimeUnit.NANOSECONDS, new
        // ScheduledThreadPoolExecutor.DelayedWorkQueue());
        // }
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
        // 2.创建任务
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("定时线程池-任务执行");
            }
        };
        // 3.通过线程池执行任务,execute 立即执行，schedule 延迟1s执行,scheduleAtFixedRate
        // 延迟1s执行之后每隔2秒执行
        // scheduledThreadPool.execute(task);
        scheduledThreadPool.schedule(task, 1000L, TimeUnit.MILLISECONDS);
        // scheduledThreadPool.scheduleAtFixedRate(task,1000L,2000L,
        // TimeUnit.MILLISECONDS);
        // 4.关闭线程池
        scheduledThreadPool.shutdown();
    }

    public static void createCachedThreadPool() {
        // 1.创建可缓存线程池
        // public static ExecutorService newCachedThreadPool() {
        // return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS,
        // new SynchronousQueue());
        // }
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        // 2.创建任务
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("可缓存线程池-任务执行");
            }
        };
        // 3.通过线程池执行任务
        cachedThreadPool.execute(task);
        // 4.关闭线程池
        cachedThreadPool.shutdown();
    }

    public static void createSingleThreadExecutor() {
        // 1.创建单线程线程池
        // public static ExecutorService newSingleThreadExecutor() {
        // return new Executors.FinalizableDelegatedExecutorService(new
        // ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new
        // LinkedBlockingQueue()));
        // }
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        // 2.创建任务
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("单线程线程池-任务执行");
            }
        };
        // 3.通过线程池执行任务
        singleThreadExecutor.execute(task);
        // 4.关闭线程池
        singleThreadExecutor.shutdown();
    }
}
